package com.elitetyc.eliteim.server.holder;

import com.elitetyc.eliteim.common.model.IMUserInfo;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author yuanchao.tan
 * @version 1.0
 * @description 连接信息管理器
 * @Date 2021/9/16 14:30
 */
public class SessionSocketHolder {
    public static final Map<String, ServerChannelUserInfo> CHANNEL_USER_INFO_MAP = new ConcurrentHashMap<>(16);

    public static void putSession(String userId,ServerChannelUserInfo userInfo){
        CHANNEL_USER_INFO_MAP.put(userId,userInfo);
    }

    public static void removeSession(String userId){
        CHANNEL_USER_INFO_MAP.remove(userId);
    }


    /**
     * 通过通道移除--当监听到某个通道无心跳之后进行移除
     * @param nioSocketChannel
     */
    public static void removeSession(NioSocketChannel nioSocketChannel){
        CHANNEL_USER_INFO_MAP.entrySet().stream().filter(it->it.getValue().channel==nioSocketChannel)
                .forEach(it->CHANNEL_USER_INFO_MAP.remove(it.getKey()));
    }

    /**
     * 通过通道获取用户信息
     * @param nioSocketChannel
     * @return
     */
    public static IMUserInfo getUserInfo(NioSocketChannel nioSocketChannel){
        final List<Map.Entry<String, ServerChannelUserInfo>> collect = CHANNEL_USER_INFO_MAP.entrySet().stream()
                .filter(it -> it.getValue().channel == nioSocketChannel).collect(Collectors.toList());
        if (collect.size()==1){
            return collect.get(0).getValue().getUserInfo();
        }else {
            return null;
        }

    }

    /**
     * 通过用户id获取用户消息通道
     * @param userId
     * @return
     */
    public static NioSocketChannel getUserChannel(String userId) {
        return CHANNEL_USER_INFO_MAP.get(userId).channel;
    }


    public static class ServerChannelUserInfo{
        private IMUserInfo userInfo;
        private NioSocketChannel channel;

        public IMUserInfo getUserInfo() {
            return userInfo;
        }

        public void setUserInfo(IMUserInfo userInfo) {
            this.userInfo = userInfo;
        }

        public NioSocketChannel getChannel() {
            return channel;
        }

        public void setChannel(NioSocketChannel channel) {
            this.channel = channel;
        }

        public ServerChannelUserInfo(IMUserInfo userInfo, NioSocketChannel channel) {
            this.userInfo = userInfo;
            this.channel = channel;
        }
    }


}
